﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using CommonUtils.Logging;

namespace CommonUtils.CommandLine
{
    /// <summary>
    /// Command line utils
    /// </summary>
    internal class CommandLineUtils
    {
        #region Singleton

        /// <summary>
        /// Default constructor
        /// </summary>
        private CommandLineUtils()
        {
        }

        /// <summary>
        /// The only instance
        /// </summary>
        private static readonly CommandLineUtils instance = new CommandLineUtils();

        /// <summary>
        /// The only instance
        /// </summary>
        public static CommandLineUtils Instance
        {
            [DebuggerStepThrough]
            get
            {
                return instance;
            }
        }

        #endregion

        #region Implementation

        /// <summary>
        /// Write formatted info about command line items
        /// </summary>
        /// <param name="map">Delegates map</param>
        internal void WriteCommandLineItemDictionaryInfo(Dictionary<string, Delegate> map)
        {
            Dictionary<string, string> itemDescriptionsMap = new Dictionary<string, string>();

            foreach (KeyValuePair<string, Delegate> keyValuePair in map)
            {
                string description = GetCommandLineItemDescription(keyValuePair.Value.Method);

                if (!string.IsNullOrEmpty(description))
                {
                    if (itemDescriptionsMap.ContainsKey(description))
                    {
                        itemDescriptionsMap[description] += string.Format(", {0}", keyValuePair.Key);
                    }
                    else
                    {
                        itemDescriptionsMap.Add(description, keyValuePair.Key);
                    }
                }
            }

            foreach (KeyValuePair<string, string> pair in itemDescriptionsMap)
            {
                Logger.Instance.PrintMessage(string.Format("\t{0}\t- {1}", pair.Value, pair.Key));
            }
        }

        /// <summary>
        /// Get description from command line item by attribute
        /// </summary>
        /// <param name="commandLineItem">Command line item</param>
        /// <returns>Description</returns>
        internal string GetCommandLineItemDescription(ICustomAttributeProvider commandLineItem)
        {
            object[] attributes = commandLineItem.GetCustomAttributes(typeof (CommandLineItemDescriptionAttribute), true);

            Logger.Instance.Assert(attributes.Length == 1, "Can`t read command line item description");

            return ((CommandLineItemDescriptionAttribute) (attributes[0])).Description;
        }

        #endregion
    }
}